二叉树的几种创建方法
@Author: 张海拔
@Update: 2014-01-28
@Link: http://www.cnblogs.com/zhanghaiba/p/3535769.html
二叉树这种数据结构非常经典。研究二叉树之前必须得创建二叉树,这里简单介绍三种常见的创建二叉树的方式——
89 ____|____ | | 73 82 _|__ ___|___ | | | | 92 5 _|__ _|__ | | | | 69 _|__ | |
(1)随机创建一棵二叉树
比如我们要随机生成含n个节点的二叉树,默认指定节点值的范围是[0, 100)
那么生成一个节点后,设随机生成的左子树包括节点数是left_n = random[0, n-1],则right_n = (n-1) - left_n
这样递归下去,当n<=0返回空,n==1返回一个根节点
该算法生成的二叉树是比较“平衡”的(期望情况下左子树和右子树数目差不多),原因是生成深度很浅时比深度很深时范围大,相对不容易取到边界值。
如上所示的二叉树,创建过程中,打印left_n和right_n结果会是:
left_n=1 right_n = 4
left_n=2 right_n = 1
left_n=1 right_n = 0
(2)根据二叉树的前序、中序或后序序列(同时包含空节点的序列)来创建
如上所示的二叉树,包括空节点的前序序列表示为:89 73 # # 82 92 69 # # # 5 # #(空节点标记为#)
中序、后序同理
(3)根据二叉树对应的“完全二叉树”序列来创建(设下标从0开始)
想象如上所示的二叉树嵌入到完全二叉树中,则从下标0~15,完全二叉树对应的序列是:
89 73 82 # # 92 5 # # # # 69 # # #
把序列存入数组order[]中,若设树的根节点值为order[idx],则其左子树根节点的值为order[idx*2 +1],右子树的为order[idx*2 +2]
(4)由遍历序列创建二叉树 link(public),这个已经单独介绍过了,包括给定中序前序创建和给定中序后序创建两种情况。
不过这种创建方式创建出来的二叉树有局限性:要求每个节点的“值”是不同的。
假如有两个节点“值”相同,比如完全二叉树的{1,1}和{1, #, 1},可以创建两棵不同的树,但它们的前序中序序列是完全一样的。
1 /* 2 *Author: ZhangHaiba 3 *Date: 2014-1-28 4 *File: binary_tree.c 5 * 6 *a demo shows three ways to create binary tree 7 */ 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <time.h> 11 #define MOD 100 12 #define LEN 1024 13 #define CMD_LEN 128 14 15 typedef struct node* link; 16 typedef struct node { 17 int item; 18 link left; 19 link right; 20 }node; 21 22 //public 23 link NODE(int item, link left, link right); 24 link bt_create_by_random(int n); 25 link bt_create_by_preorder(void); 26 //idx begin with 0 27 link bt_create_by_complete_bt_order(int *order, int order_len, int idx); 28 link bt_preorder(link root); 29 void bt_show_by_tree(link root); 30 31 //private 32 link bt_create_by_random_core(int n); 33 void tree_print(link root, FILE *fd); 34 35 36 int main(void) 37 { 38 char cmd[CMD_LEN]; 39 int n, i, order[LEN]; 40 41 printf("there is three ways to create binary tree, including:\n"); 42 printf("[r] create binary tree by random\n"); 43 printf("[p] create binary tree by preorder(NULL node values -1)\n"); 44 printf("[c] create binary tree by complete binary tree order(NULL node values -1)\n"); 45 printf("[q] quit\n"); 46 printf("please choice: enter charactor 'r' 'p' or 'c', or 'q' to quit\n"); 47 while(1) { 48 scanf("%s", cmd); 49 switch(cmd[0]) { 50 case 'r': 51 printf("create binary tree with n nodes by randmon, please assgin n:\n"); 52 scanf("%d", &n); 53 link bt_tree_a = bt_create_by_random(n); 54 bt_show_by_tree(bt_tree_a); 55 break; 56 case 'p': 57 printf("please input preorder(NULL node values -1)\n"); 58 link bt_tree_b = bt_create_by_preorder(); 59 bt_show_by_tree(bt_tree_b); 60 break; 61 case 'c': 62 printf("to create complete binary tree order, assgin its length as:\n"); 63 scanf("%d", &n); 64 printf("please input complete binary tree order(NULL node values -1)\n"); 65 for (i = 0; i < n; ++i) 66 scanf("%d", order+i); 67 link bt_tree_c = bt_create_by_complete_bt_order(order, n, 0); 68 bt_show_by_tree(bt_tree_c); 69 break; 70 case 'q': 71 return 0; 72 default: 73 break; 74 } 75 } 76 return 0; 77 } 78 79 link NODE(int item, link left, link right) 80 { 81 link born = malloc( sizeof (node) ); 82 born->item = item; 83 born->left = left; 84 born->right = right; 85 return born; 86 } 87 88 link bt_create_by_random(int n) 89 { 90 srand( (unsigned)time(NULL) ); 91 return bt_create_by_random_core(n); 92 } 93 94 link bt_create_by_random_core(int n) 95 { 96 if (n <= 0) 97 return NULL; 98 if (n == 1) 99 return NODE(rand()%MOD, NULL, NULL); 100 101 link root = NODE(rand()%MOD, NULL, NULL); 102 int left_n = rand()%(n-1) + 1, right_n = (n-1) - left_n; 103 root->left = bt_create_by_random_core(left_n); 104 root->right = bt_create_by_random_core(right_n); 105 return root; 106 } 107 108 link bt_create_by_preorder(void) 109 { 110 int item; 111 112 scanf("%d", &item); 113 if (item == -1) //current root is NULL 114 return NULL; 115 link root = NODE(item, NULL, NULL); 116 root->left = bt_create_by_preorder(); 117 root->right = bt_create_by_preorder(); 118 return root; 119 } 120 121 122 link bt_create_by_complete_bt_order(int *order, int n, int idx) 123 { 124 if (order[idx] == -1 || idx >= n) 125 return NULL; 126 link root = NODE(order[idx], NULL, NULL); 127 root->left = bt_create_by_complete_bt_order(order, n, idx*2+1); 128 root->right = bt_create_by_complete_bt_order(order, n, idx*2+2); 129 return root; 130 } 131 132 void bt_show_by_tree(link root) 133 { 134 char cmd[CMD_LEN]; 135 136 sprintf(cmd, "rm -f ./tree_src.txt"); 137 system(cmd); 138 139 FILE *fd = fopen("./tree_src.txt", "a+"); 140 fprintf(fd, "\n\t\\tree"); 141 tree_print(root, fd); 142 fprintf(fd, "\n\n"); 143 fclose(fd); 144 145 sprintf(cmd, "cat ./tree_src.txt | ~/tree/tree"); 146 system(cmd); 147 } 148 149 void tree_print(link root, FILE *fd) 150 { 151 fprintf(fd, "("); 152 if (root != NULL) { 153 fprintf(fd, "%d", root->item); 154 tree_print(root->left, fd); 155 tree_print(root->right, fd); 156 } 157 fprintf(fd, ")"); 158 }
测试示范:
ZhangHaiba-MacBook-Pro:code apple$ ./a.out there is 3 way to create binary tree, including: [r] create binary tree by random [p] create binary tree by preorder(NULL node values -1) [c] create binary tree by complete binary tree order(NULL node values -1) [q] quit please choice: enter charactor 'r' 'p' or 'c', or 'q' to quit r create binary tree with n nodes by randmon, please assgin n: 4 19 ___|___ | | 61 49 _|__ _|__ | | | | 67 _|__ | | r create binary tree with n nodes by randmon, please assgin n: 10 33 _|__ | | 60 ____|_____ | | 80 6 _|__ ___|___ | | | | 43 93 54 ___|___ _|__ _|__ | | | | | | 67 31 40 _|__ _|__ _|__ | | | | | | r create binary tree with n nodes by randmon, please assgin n: 10 61 ____|_____ | | 11 89 _|__ ___|___ | | | | 34 58 _|__ _|__ | | | | 50 ___|___ | | 79 58 _|__ _|__ | | | | 81 _|__ | | 22 _|__ | | r create binary tree with n nodes by randmon, please assgin n: 10 38 ____|_____ | | 38 8 _|__ ____|____ | | | | 54 14 62 _|__ _|__ ___|___ | | | | | | 3 68 9 _|__ _|__ _|__ | | | | | | 42 _|__ | | p please input preorder(NULL node values -1) 89 73 -1 -1 82 92 69 -1 -1 -1 5 -1 -1 89 ____|____ | | 73 82 _|__ ___|___ | | | | 92 5 _|__ _|__ | | | | 69 _|__ | | c to create complete binary tree order, assgin its length as: 15 please input complete binary tree order(NULL node values -1) 89 73 82 -1 -1 92 5 -1 -1 -1 -1 69 -1 -1 -1 89 ____|____ | | 73 82 _|__ ___|___ | | | | 92 5 _|__ _|__ | | | | 69 _|__ | | q